home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-SPAR.{_6 / SOFTIRQ.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  4KB  |  174 lines

  1. /* softirq.h: 32-bit Sparc soft IRQ support.
  2.  *
  3.  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  4.  * Copyright (C) 1998 Anton Blanchard (anton@progsoc.uts.edu.au)
  5.  */
  6.  
  7. #ifndef __SPARC_SOFTIRQ_H
  8. #define __SPARC_SOFTIRQ_H
  9.  
  10. #include <asm/atomic.h>
  11. #include <asm/smp.h>
  12. #include <asm/hardirq.h>
  13.  
  14. extern unsigned int local_bh_count[NR_CPUS];
  15.  
  16. #define get_active_bhs()    (bh_mask & bh_active)
  17.  
  18. #ifdef __SMP__
  19.  
  20. /*
  21.  * The locking mechanism for base handlers, to prevent re-entrancy,
  22.  * is entirely private to an implementation, it should not be
  23.  * referenced at all outside of this file.
  24.  */
  25. extern atomic_t global_bh_lock;
  26. extern atomic_t global_bh_count;
  27. extern spinlock_t sparc_bh_lock;
  28.  
  29. extern void synchronize_bh(void);
  30.  
  31. static inline void clear_active_bhs(unsigned int mask)
  32. {
  33.     unsigned long flags;
  34.     spin_lock_irqsave(&sparc_bh_lock, flags);
  35.     bh_active &= ~(mask);
  36.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  37. }
  38.  
  39. extern inline void init_bh(int nr, void (*routine)(void))
  40. {
  41.     unsigned long flags;
  42.     spin_lock_irqsave(&sparc_bh_lock, flags);
  43.     bh_base[nr] = routine;
  44.     atomic_set(&bh_mask_count[nr], 0);
  45.     bh_mask |= 1 << nr;
  46.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  47. }
  48.  
  49. extern inline void remove_bh(int nr)
  50. {
  51.     unsigned long flags;
  52.     spin_lock_irqsave(&sparc_bh_lock, flags);
  53.     bh_mask &= ~(1 << nr);
  54.     bh_base[nr] = NULL;
  55.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  56. }
  57.  
  58. extern inline void mark_bh(int nr)
  59. {
  60.     unsigned long flags;
  61.     spin_lock_irqsave(&sparc_bh_lock, flags);
  62.     bh_active |= (1 << nr);
  63.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  64. }
  65.  
  66. /*
  67.  * These use a mask count to correctly handle
  68.  * nested disable/enable calls
  69.  */
  70. extern inline void disable_bh(int nr)
  71. {
  72.     unsigned long flags;
  73.     spin_lock_irqsave(&sparc_bh_lock, flags);
  74.     bh_mask &= ~(1 << nr);
  75.     atomic_inc(&bh_mask_count[nr]);
  76.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  77.     synchronize_bh();
  78. }
  79.  
  80. extern inline void enable_bh(int nr)
  81. {
  82.     unsigned long flags;
  83.     spin_lock_irqsave(&sparc_bh_lock, flags);
  84.     if (atomic_dec_and_test(&bh_mask_count[nr]))
  85.         bh_mask |= 1 << nr;
  86.     spin_unlock_irqrestore(&sparc_bh_lock, flags);
  87. }
  88.  
  89. static inline void start_bh_atomic(void)
  90. {
  91.     atomic_inc(&global_bh_lock);
  92.     synchronize_bh();
  93. }
  94.  
  95. static inline void end_bh_atomic(void)
  96. {
  97.     atomic_dec(&global_bh_lock);
  98. }
  99.  
  100. /* These are for the IRQs testing the lock */
  101. static inline int softirq_trylock(int cpu)
  102. {
  103.     if (atomic_add_return(1, &global_bh_count) == 1) {
  104.         if (atomic_read(&global_bh_lock) == 0) {
  105.             ++local_bh_count[cpu];
  106.             return 1;
  107.         }
  108.     }
  109.     atomic_dec(&global_bh_count);
  110.     return 0;
  111. }
  112.  
  113. static inline void softirq_endlock(int cpu)
  114. {
  115.     local_bh_count[cpu]--;
  116.     atomic_dec(&global_bh_count);
  117. }
  118.  
  119. #else
  120.  
  121. #define clear_active_bhs(x)    (bh_active &= ~(x))
  122. #define mark_bh(nr)        (bh_active |= (1 << (nr)))
  123.  
  124. /* These are for the irq's testing the lock */
  125. #define softirq_trylock(cpu)    (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
  126. #define softirq_endlock(cpu)    (local_bh_count[cpu] = 0)
  127. #define synchronize_bh()    barrier()
  128.  
  129. /*
  130.  * These use a mask count to correctly handle
  131.  * nested disable/enable calls
  132.  */
  133. extern inline void disable_bh(int nr)
  134. {
  135.     bh_mask &= ~(1 << nr);
  136.     atomic_inc(&bh_mask_count[nr]);
  137.     synchronize_bh();
  138. }
  139.  
  140. extern inline void enable_bh(int nr)
  141. {
  142.     if (atomic_dec_and_test(&bh_mask_count[nr]))
  143.         bh_mask |= 1 << nr;
  144. }
  145.  
  146. extern inline void init_bh(int nr, void (*routine)(void))
  147. {
  148.     bh_base[nr] = routine;
  149.     atomic_set(&bh_mask_count[nr], 0);
  150.     bh_mask |= 1 << nr;
  151. }
  152.  
  153. extern inline void remove_bh(int nr)
  154. {
  155.     bh_mask &= ~(1 << nr);
  156.     bh_base[nr] = NULL;
  157. }
  158.  
  159. extern inline void start_bh_atomic(void)
  160. {
  161.     local_bh_count[0]++;
  162.     barrier();
  163. }
  164.  
  165. extern inline void end_bh_atomic(void)
  166. {
  167.     barrier();
  168.     local_bh_count[0]--;
  169. }
  170.  
  171. #endif    /* SMP */
  172.  
  173. #endif    /* __SPARC_SOFTIRQ_H */
  174.